package impl

import (
	"context"
	"fmt"
	"time"

	"dario.cat/mergo"
	"gitee.com/go-kade/go12/vblog/apps/blog"
)

func (i *BlogServiceImpl) CreateBlog(ctx context.Context, bl *blog.CreateBlogRequest) (*blog.Blog, error) {
	ins := blog.NewBlog(bl)
	// db, _ := gorm.Open(mysql.Open("root:cys000522@tcp(34.28.164.10:3306)/go12?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{})
	if err := i.db.WithContext(ctx).Create(ins).Error; err != nil {
		return nil, err
	}
	return ins, nil
}

func (i *BlogServiceImpl) UpdateBlogStatus(ctx context.Context, bl *blog.UpdateBlogStatusRequest) (*blog.Blog, error) {
	return nil, nil
}
func (i *BlogServiceImpl) UpdateBlog(ctx context.Context, bl *blog.UpdateBlogRequest) (*blog.Blog, error) {
	// 查询需要更新的对象
	ins, err := i.DescribeBlog(ctx, blog.NewDescribeBlogRequest(bl.BlogId))
	if err != nil {
		return nil, err
	}
	// 更新模式
	switch bl.UpdateMode {
	case blog.UPDATE_MODE_PUT:
		// 全量更新
		ins.CreateBlogRequest = bl.CreateBlogRequest
	case blog.UPDATE_MODE_PATCH:
		// 增量更新
		// if in.Author != "" {
		// 	ins.Author = in.Author
		// }
		// if in.Content != "" {
		// 	ins.Content = in.Content
		// }

		// 有没有工具来帮我们完成2个结构体的merge
		// "dario.cat/mergo"
		err := mergo.Merge(ins.CreateBlogRequest, bl.CreateBlogRequest, mergo.WithOverride) //如果有相同的。覆盖结构体
		if err != nil {
			return nil, err
		}
	default:
		return nil, fmt.Errorf("unknown update mode: %d", bl.UpdateMode)
	}
	// 更新数据
	// UPDATE `blogs` SET `created_at`=1696477297,`updated_at`=1696487853,`status`='1',`title`='Vblog Web Service Api2',`content`='Golang2',`tags`='{"分类":"Golang"}' WHERE id = '43' AND `id` = 43
	ins.UpdateTime = time.Now().Unix()
	// err = i.db.WithContext(ctx).Where("id = ?", bl.BlogId).Updates(ins).Error
	err = i.update(ctx, bl.Scope, ins)

	if err != nil {
		return nil, err
	}
	return ins, nil
}
func (i *BlogServiceImpl) DeleteBlog(ctx context.Context, bl *blog.DeleteBlogRequest) error {
	return i.db.WithContext(ctx).Model(&blog.Blog{}).Where("id = ?", bl.BlogId).Delete(&blog.Blog{}).Error
}

func (i *BlogServiceImpl) QueryBlog(ctx context.Context, bl *blog.QueryBlogRequest) (*blog.BlogSet, error) {
	// 提前准备好Set对象
	set := blog.NewBlogSet()
	query := i.db.WithContext(ctx).Model(&blog.Blog{})

	// 组装查询条件
	if bl.Status != nil {
		query = query.Where("status = ?", *bl.Status) //query = query  因为在if里面，是不生效的所以要重新赋值给外面
	}
	if bl.Keywords != "" {
		// 关键字过滤: 模糊匹配,  Golang入门   Golang
		// ? 占位符 '%Test12%'
		query = query.Where("title LIKE ?", "%"+bl.Keywords+"%")
	}
	if len(bl.Usernames) > 0 {
		// gorm 会把 [] --> (xxx,xxx)
		query = query.Where("create_by_name IN ?", bl.Usernames)
	}

	// 1. 查询总数量
	err := query.Count(&set.Total).Error
	if err != nil {
		return nil, err
	}
	// 2. 查询一页的数据
	// fmt.Println("------",bl.PageSize)
	err = query.Offset(bl.Offset()).Limit(bl.PageSize).Find(&set.Items).Error
	if err != nil {
		return nil, err
	}
	return set, nil
}

// 详情页, 尽量多的把关联的数据查询出来， content
func (i *BlogServiceImpl) DescribeBlog(ctx context.Context, bl *blog.DescribeBlogRequest) (*blog.Blog, error) {
	query := i.db.WithContext(ctx).Model(&blog.Blog{})
	ins := blog.NewBlog(blog.NewCreateBlogRequest())

	// SELECT * FROM `blogs` WHERE id = '1' ORDER BY `blogs`.`id` LIMIT 1
	err := query.Where("id = ?", bl.BlogId).First(ins).Error
	if err != nil {
		return nil, err
	}
	return ins, nil
}

// 文章审核, 审核通过的文章才能被看到
func (i *BlogServiceImpl) AuditBlog(ctx context.Context, bl *blog.AuditBlogRequest) (*blog.Blog, error) {
	// 查询需要更新的对象
	ins, err := i.DescribeBlog(ctx, blog.NewDescribeBlogRequest(bl.BlogId))
	if err != nil {
		return nil, err
	}

	ins.IsAuditPass = bl.IsAuditPass
	ins.AuditAt = time.Now().Unix()
	err = i.update(ctx, nil, ins)
	if err != nil {
		return nil, err
	}
	return ins, err
}
